﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using MindFusion.Diagramming;
using System.Data.Common;
using System.Data.SqlClient;
using System.IO;
using System.Diagnostics;


namespace Inference
{
    public partial class ReasonForm : Form
    {

        TaleEntities Tale;

        public ReasonForm(TaleEntities _tale)
        {
            InitializeComponent();
            Tale = _tale;
        }


        List<TreeNode> GetNodes(string name)
        {
            List<TreeNode> nodes = new List<TreeNode>();
                var Sl = from f in Tale.ViewValues
                         orderby f.Number
                         where f.FrameName.ToLower().Trim() == name.ToLower().Trim() && f.Number!=0
                         select f;
                foreach (var s in Sl)
                {

                    TreeNode node=new TreeNode("'" + s.Name + "' : '" + s.Value + "'");
                    if (Tale.Frame.Where(f => f.Name.ToLower().Trim() == s.Value.ToLower().Trim()).Count() > 0) // если  субфрейм
                        node.Nodes.AddRange(GetNodes(s.Value).ToArray());
                    nodes.Add(node);
                }
            return nodes;
        }


        int GetLastIndex(string FrameID)
        {
            int index=-1;
            for (int i = 0; i < TreeRules.Nodes["root"].Nodes.Count; i++)
                if (TreeRules.Nodes["root"].Nodes[i].ImageKey == FrameID)
                    index = i;
                return index;
        }

        void ClearTreeFromEntities()
        {
            TreeNode Root=TreeRules.Nodes["root"];
            for (int i = Root.Nodes.Count - 1; i >= 0; i--)
            {
                int key= int.Parse(Root.Nodes[i].ImageKey);
                int valueid=Tale.ViewFrameExample.Where(f=>f.ID==key).First().ValueID;
                if (Tale.DomainsValues.Where(d => d.Value == valueid).First().DomID == 1)
                    Root.Nodes[i].Remove();
            }
        }

        private void ReasonForm_Load(object sender, EventArgs e)
        {
            // заполнение списка фреймов
            var Frames = from s in Tale.Log where s.Slot.Number!=0 select s;
            int FrameID = 0;
            bool test = true;
            bool frame=true;
            TreeNode Root=TreeRules.Nodes["root"];

            foreach (var row in Frames)
            {
                string val = Tale.DValues.Where(d => d.ID == row.ValueID).First().Value;
                TreeNode node; TreeNode Fnode;
                frame=(Tale.DValues.Where(d => d.Value == row.Slot.Frame.Name).First().DomainsValues.First().Domains.ID == 7); ///!!!
                if (frame) // если ситуация
                {
                    if (FrameID == row.Slot.Frame.ID)
                        test = true;
                    else
                        test = false;
                    FrameID = row.Slot.Frame.ID;
                }
                if (Root.Nodes.ContainsKey(row.Slot.FrameID.ToString()) && test)
                {
                    node = Root.Nodes[Root.Nodes.IndexOfKey(row.Slot.FrameID.ToString())].Nodes.Add("'" + row.Slot.Name + "' : '" + val + "'");
                }
                else
                {
                    if ((!test && Root.Nodes.ContainsKey(row.Slot.FrameID.ToString()))
                        //&& !frame)
                        && Root.Nodes[GetLastIndex((row.Slot.FrameID.ToString()))].ForeColor != Color.Red)
                    {
                        Fnode = Root.Nodes[GetLastIndex((row.Slot.FrameID.ToString()))]; // для изменения состояния(например)
                    }
                    else
                    {
                        // добавляем в корень
                        Fnode = Root.Nodes.Add(row.Slot.FrameID.ToString(), row.Slot.Frame.Name, row.Slot.FrameID.ToString());
                        FontFamily ff = FontFamily.Families[237];
                        Font F = new Font(ff, 10, FontStyle.Bold);
                        if (FrameID == row.Slot.Frame.ID)
                            //Fnode.ForeColor = Color.MediumSeaGreen;
                            Fnode.NodeFont = F;
                    }
                    node = Fnode.Nodes.Add("'" + row.Slot.Name + "' : '" + val + "'");
                }
                    int fid = 0;
                    if (Tale.Frame.Where(f => f.Name.ToLower().Trim() == val.ToLower().Trim()).Count() > 0)
                        fid = Tale.Frame.Where(f => f.Name.ToLower().Trim() == val.ToLower().Trim()).First().ID;                   
                    //// перетягиваем сущность к ситуации
                    if (Root.Nodes.ContainsKey(fid.ToString()))
                    {
                        TreeNode rnode = (TreeNode)Root.Nodes[fid.ToString()].Clone();
                        //TreeRules.Nodes["root"].Nodes[fid.ToString()].Remove();
                        node.Nodes.AddRange(rnode.Nodes.Cast<TreeNode>().ToArray());
                    }
                    else
                    { 
                    }
                

                if (row.Success)
                {
                    node.Parent.ForeColor = Color.Green;
                }
                else
                {
                    node.ForeColor = Color.Red;
                    node.Parent.ForeColor = Color.Red;
                }
              
            }
            ClearTreeFromEntities();
            TreeRules.Nodes["root"].Expand();

            // заполнение списка фреймов-экземпляров
            var FramesID = from s in Tale.ViewValues select s.FrameID;

            foreach(var id in FramesID.Distinct())
            {
                TreeNode node = TreeChain.Nodes["root"].Nodes.Add(Tale.Frame.Where(f=>f.ID==id).First().Name);                
                FontFamily ff = FontFamily.Families[237];
                Font F = new Font(ff, 10, FontStyle.Bold);
                //node.ForeColor=Color.Green;
                node.NodeFont = F;
                var Slots = from f in Tale.ViewValues orderby f.Number where f.FrameID==id && f.Number!=0 select f;
                foreach (var Slot in Slots)
                {
                    TreeNode SubNode = node.Nodes.Add("'" + Slot.Name + "' : '" + Slot.Value + "'");
                    if (Tale.Frame.Where(f => f.Name.ToLower().Trim() == Slot.Value.ToLower().Trim()).Count() > 0) // если  субфрейм
                        SubNode.Nodes.AddRange(GetNodes(Slot.Value).ToArray());
                }
                
            }

            TreeChain.Nodes["root"].Expand();

            // заполнение списка переменных
            //TreeRules.ClientSizeChanged += new EventHandler(TreeRules_ClientSizeChanged);
            //TreeChain.ClientSizeChanged += new EventHandler(TreeChain_ClientSizeChanged);
            //int index = 0;
            //GridReasonVars.Rows.Clear();
            //foreach (KeyValuePair<int, int> var in WorkingMemory.KnownVars.ToList())
            //{
            //    index = GridReasonVars.Rows.Add();
            //    GridReasonVars[0, index].Value = KB.Vars.GetVarById(var.Key).Reason;
            //    GridReasonVars[1, index].Value = KB.Vars.GetVarById(var.Key).type;
            //    GridReasonVars[2, index].Value = KB.Domains.GetDomainValueNameById(KB.Vars.GetVarById(var.Key).domain, var.Value);
            //}
            //foreach (int var in KB.Vars.Vars.Keys.ToList())
            //{
            //    if (!WorkingMemory.KnownVars.ContainsKey(var))
            //    {
            //        index = GridReasonVars.Rows.Add();
            //        GridReasonVars[0, index].Value = KB.Vars.GetVarById(var).Name;
            //        GridReasonVars[1, index].Value = KB.Vars.GetVarById(var).type;
            //        GridReasonVars[2, index].Value = "не означена";
            //    }
            //}

            // заполнение цепи вывода
            //foreach (int r in WorkingMemory.Chain)
            //{
            //    Rule rul = KB.Rules.GetRuleById(r);
            //    TreeNode node = TreeChain.Nodes["root"].Nodes.Add(rul.Name);
            //    node.Nodes.Add("IF");
            //    foreach (RulePair rp in rul.IfVars)
            //        node.Nodes.Add("'" + KB.Vars.GetVarById(rp.Variable).Name + "'=='" +
            //            KB.Domains.GetDomainValueNameById(KB.Vars.GetVarById(rp.Variable).domain, rp.Value) + "'");
            //    node.Nodes.Add("THEN");
            //    foreach (RulePair rp in rul.ThenVars)
            //        node.Nodes.Add("'" + KB.Vars.GetVarById(rp.Variable).Name + "'='" +
            //            KB.Domains.GetDomainValueNameById(KB.Vars.GetVarById(rp.Variable).domain, rp.Value) + "'");
            //    node.Nodes.Add("Объяснение: '" + rul.Reason + "'");
            //}
            //if (WorkingMemory.Chain.Count == 0)
            //    TreeChain.Nodes["root"].Nodes.Add("Список пуст");
            //TreeChain.Nodes["root"].Expand();

            //заполнение cписка всех правил
            //int i = 0;
            //foreach (int r in WorkingMemory.AllRules)
            //{
            //    List<RulePair> WrongFacts = new List<RulePair>();
            //    Rule rul = KB.Rules.GetRuleById(r);
            //    TreeNode node = TreeRules.Nodes["root"].Nodes.Add(rul.Name);
            //    TreeNode MainNode = new TreeNode(); MainNode = node;
            //    if (WorkingMemory.Chain.Contains(r))
            //        node.ForeColor = Color.Green;
            //    else
            //    {
            //        node.ForeColor = Color.Red;
            //        node = node.Nodes.Add("Правило");
            //    }
            //    node.Nodes.Add("IF");
            //    foreach (RulePair rp in rul.IfVars)
            //    {
            //        TreeNode NodeIf = node.Nodes.Add("'" + KB.Vars.GetVarById(rp.Variable).Name + "'=='" +
            //            KB.Domains.GetDomainValueNameById(KB.Vars.GetVarById(rp.Variable).domain, rp.Value) + "'");
            //        if (WorkingMemory.ForAll.Count > rul.IfVars.IndexOf(rp))
            //            if (WorkingMemory.ForAll[i][rul.IfVars.IndexOf(rp)].val != rp.Value)
            //            {
            //                NodeIf.ForeColor = Color.Red;
            //            }
            //    }
            //    node.Nodes.Add("THEN");
            //    foreach (RulePair rp in rul.ThenVars)
            //        node.Nodes.Add("'" + KB.Vars.GetVarById(rp.Variable).Name + "'='" +
            //            KB.Domains.GetDomainValueNameById(KB.Vars.GetVarById(rp.Variable).domain, rp.Value) + "'");
            //    node.Nodes.Add("Объяснение: '" + rul.Reason + "'");
            //    if (MainNode.ForeColor == Color.Red) // если правило не сработало
            //    {
            //        TreeNode ActFacts = MainNode.Nodes.Add("Значение посылки на момент вывода");
            //        foreach (WorkingMemory.pair rp in WorkingMemory.ForAll[i])
            //            if (rp.val > -1)
            //                ActFacts.Nodes.Add("'" + KB.Vars.GetVarById(rp.var).Name + "'='" +
            //                     KB.Domains.GetDomainValueNameById(KB.Vars.GetVarById(rp.var).domain, rp.val) + "'");
            //            else
            //                ActFacts.Nodes.Add("'" + KB.Vars.GetVarById(rp.var).Name + "'=не означено'");
            //        ActFacts.Expand();
            //        node.Expand();
            //    }
            //    i++;

            //}
            //if (WorkingMemory.AllRules.Count == 0)
            //    TreeRules.Nodes["root"].Nodes.Add("Список пуст");
            //TreeRules.Nodes["root"].Expand();

        }

        void TreeChain_ClientSizeChanged(object sender, EventArgs e)
        {
            button3.Location = new Point(TreeChain.ClientSize.Width - 40, button3.Location.Y);
            button4.Location = new Point(TreeChain.ClientSize.Width - 40, button4.Location.Y);
        }

        void TreeRules_ClientSizeChanged(object sender, EventArgs e)
        {
            button1.Location = new Point(TreeRules.ClientSize.Width - 40, button1.Location.Y);
            button2.Location = new Point(TreeRules.ClientSize.Width - 40, button2.Location.Y);
        }



        private void button2_Click_1(object sender, EventArgs e)
        {
            if (TreeRules.SelectedNode != null)
            {
                TreeRules.SelectedNode.Collapse();
                if (TreeRules.SelectedNode == TreeRules.Nodes["root"])
                    TreeRules.SelectedNode.Expand();
            }
        }

        private void button1_Click_1(object sender, EventArgs e)
        {
            if (TreeRules.SelectedNode != null)
            TreeRules.SelectedNode.ExpandAll();
        }

        private void button4_Click_1(object sender, EventArgs e)
        {
            if (TreeChain.SelectedNode != null)
            TreeChain.SelectedNode.ExpandAll();
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            if (TreeChain.SelectedNode != null)
            {
                TreeChain.SelectedNode.Collapse();
                if (TreeChain.SelectedNode == TreeChain.Nodes["root"])
                    TreeChain.SelectedNode.Expand();
            }
        }

        private void BtnOK_Click(object sender, EventArgs e)
        {
            this.Close();
        }



    }
}
